/*
 *  linux/kernel/reboot.c
 *
 *  Copyright (C) 2013  Linus Torvalds
 */

#define pr_fmt(fmt)	KBUILD_BASENAME ": " fmt

#include <seminix/kernel.h>
#include <seminix/cpu.h>
#include <seminix/cpumask.h>
#include <seminix/reboot.h>
#include <seminix/start_kernel.h>
#include <seminix/sched.h>

#define DEFAULT_REBOOT_MODE	= REBOOT_HARD

enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE;

static void kernel_restart_prepare(void)
{
    system_state = SYSTEM_RESTART;
}

static void migrate_to_reboot_cpu(void)
{
    int cpu = boot_cpu_id();

    if (!cpu_online(cpu))
        cpu = cpumask_first(cpu_online_mask);

    set_cpus_allowed_ptr(current, cpumask_of(cpu));
}

/**
 *	kernel_restart - reboot the system
 *	@cmd: pointer to buffer containing command to execute for restart
 *		or %NULL
 *
 *	Shutdown everything and perform a clean reboot.
 *	This is not safe to call in interrupt context.
 */
void kernel_restart(char *cmd)
{
    kernel_restart_prepare();
    migrate_to_reboot_cpu();
    if (!cmd)
        pr_emerg("Restarting system\n");
    else
        pr_emerg("Restarting system with command '%s'\n", cmd);
    machine_restart(cmd);
}

static void kernel_shutdown_prepare(enum system_states state)
{
    system_state = state;
}

/**
 *	kernel_halt - halt the system
 *
 *	Shutdown everything and perform a clean system halt.
 */
void kernel_halt(void)
{
    kernel_shutdown_prepare(SYSTEM_HALT);
    migrate_to_reboot_cpu();
    pr_emerg("System halted\n");
    machine_halt();
}

/**
 *	kernel_power_off - power_off the system
 *
 *	Shutdown everything and perform a clean system power_off.
 */
void kernel_power_off(void)
{
    kernel_shutdown_prepare(SYSTEM_POWER_OFF);
    migrate_to_reboot_cpu();
    pr_emerg("Power down\n");
    machine_power_off();
}
